﻿Imports ACompany.OrderProcessing.Model
Imports ACompany.OrderProcessing.Services
Imports ACompany.OrderProcessing.Infrastructure
Imports StructureMap

Public Class CustomersController
    Inherits System.Web.Mvc.Controller

    Private CustomerService As ICustomerService

    Public Sub New()

    End Sub

    Public Sub New(ByVal CustomerService As ICustomerService)
        Me.CustomerService = CustomerService
    End Sub

    Public Function Index()

        Dim Customers As IList(Of Customer) = CustomerService.FindAll

        Return View("CustomerList", Customers)
    End Function

    Public Function Details(ByVal Id As String)

        Dim SelectedCustomerId As Guid = New Guid(Id)

        Dim Customer As Customer = CustomerService.FindBy(SelectedCustomerId)

        Return View("CustomerDetail", Customer)
    End Function

    Public Function Edit(ByVal Id As String)

        Dim SelectedCustomerId As Guid = New Guid(Id)

        Dim Customer As Customer = CustomerService.FindBy(SelectedCustomerId)

        Return View("CustomerDetailEdit", Customer)
    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Public Function Edit(ByVal Id As String, ByVal formValues As FormCollection)

        Dim SelectedCustomerId As Guid = New Guid(Id)
        Dim brokenRules As New List(Of BrokenRule)
        Dim Customer As Customer = CustomerService.FindBy(SelectedCustomerId)        

        Try
            Update(Customer)
        Catch ex As InvalidAddressException
            brokenRules.Add(New BrokenRule("Address", ex.Message))
        End Try


        If Customer.GetBrokenRules.Count = 0 And brokenRules.Count = 0 Then
            CustomerService.Save(Customer)
            ' Perform HTTP redirect to details page for the saved Customer
            Return RedirectToAction("Details", New With {.id = Customer.Id.ToString})
        Else
            ' Rules broken
            For Each br In Customer.GetBrokenRules
                brokenRules.Add(br)
            Next

            ModelState.AddRuleViolations(brokenRules)

            Return View("CustomerDetailEdit", Customer)
        End If

    End Function

    Public Function Add()

        Dim NewCustomer As New Customer
        Dim BlankAddress As New NullAddress()

        NewCustomer.Address = BlankAddress

        Return View("CustomerAdd", NewCustomer)

    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Public Function Add(ByVal formValues As FormCollection)

        Dim NewCustomer As New Customer
        Dim brokenRules As New List(Of BrokenRule)
        Dim AddNullAddress As Boolean = False

        Try
            Update(NewCustomer)
        Catch ex As InvalidAddressException
            brokenRules.Add(New BrokenRule("Address", ex.Message))
            AddNullAddress = True
        End Try

        If NewCustomer.GetBrokenRules.Count = 0 Then
            CustomerService.Save(NewCustomer)
            ' Perform HTTP redirect to details page for the newly added Customer
            Return RedirectToAction("Details", New With {.id = NewCustomer.Id.ToString})
        Else
            ' Extension method
            For Each br In NewCustomer.GetBrokenRules
                brokenRules.Add(br)
            Next

            ModelState.AddRuleViolations(brokenRules)
            ' Rules broken
            If AddNullAddress Then
                NewCustomer.Address = New NullAddress
            End If

            Return View("CustomerDetailEdit", NewCustomer)
        End If

    End Function

    Private Sub Update(ByVal Customer As Customer)

        Dim UpdatedAddress As Address

        With Customer
            .Name = Request.Form("Name")
            .Email = Request.Form("Email")

            UpdatedAddress = New Address(Request.Form("Street"), _
                                         Request.Form("City"), _
                                         Request.Form("County"), _
                                         Request.Form("PostCode"))

            .Address = UpdatedAddress
        End With

    End Sub

End Class
